﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data;
using Poligono.Core;
using System.Threading;

namespace Poligono.Data
{
    /// <summary>
    /// Class that executes commands to manipulate and query data(SQL).
    /// </summary>
    public partial class DbUtil : DisposeControl
    {
        #region private compomentes

        private DataAcessProvider _DataAcessProvider;
        //Keep tpe of command, like Select, StoredProcedure
        private TypeCommandWrapper _TypeCommandWrapper;



        #endregion


        #region Class Constructor

        /// <summary>
        /// Class Constructor to DbUtil
        /// </summary>
        public DbUtil()
        {
                
        }


        /// <summary>
        /// Class Constructor
        /// </summary>
        /// <param name="commandText">SQL command that will be executed</param>
        /// <param name="typeCommand">type of command <see cref="TypeCommand"/></param>
        public DbUtil(string commandText, CommandType typeCommand): this()
        {
#warning Implemented
            throw new NotImplementedException();
            //Sql = sql;
        }

        #endregion Class Constructor

        #region Method






        /// <summary>
        /// Menssager of erro <see cref="ObjectDisposedException"/>
        /// </summary>
        protected override string MensagemErroObjectDisposedException
        {
            get
            {
                return string.Format("ThreadID: {0} Identity: {0}",
                    Thread.CurrentThread.ManagedThreadId
                    , Thread.CurrentPrincipal.Identity.Name);
            }
        }
        #endregion



        /*
        #region Declaring properties
        //Class that connects to the database and executes the commands in transactional blocks or not
        private Scope scope = Scope.Current;// GetScope();

        //Private SQL command that will be used
        private string sql;

        /// <summary>
        /// Property that will store / retrieve the sql command to be executed
        /// </summary>
        public string Sql
        {
            get
            {
                return sql;
            }
            set
            {
                sql = value;
                scope.DataAcessProvider.Command.CommandText = sql;
            }
        }
        #endregion Declaring properties

        #region Declaring Methods

        /// <summary>
        /// Method that adds parameters to the variable "cmd" to execute the command passed in the constructor or the property of the class
        /// </summary>
        /// <param name="name">parameter name</param>
        /// <param name="type">parameter type</param>
        /// <param name="value">parameter value</param>
        /// <remarks>
        /// Author: Marco Octávio
        /// Last Update: 02/02/2009</remarks>
        public void AddParameter(string name, DbType type, object value)
        {
            try
            {
                DbParameter param = scope.DataAcessProvider.ProviderFactory.CreateParameter();
                param.ParameterName = name;
                param.DbType = type;
                param.Value = value == null ? DBNull.Value : value;
                scope.Command.Parameters.Add(param);
            }
            catch (SqlException e)
            {
                FinalizeSqlExecution(true);
                throw e;
            }
            catch (Exception e)
            {
                FinalizeSqlExecution(true);
                throw e;
            }
        }

        /// <summary>
        /// Method that terminates the execution of a method Sql
        /// </summary>
        private void FinalizeSqlExecution(bool rollback)
        {
            scope.DisposeSql(rollback);
        }

        /// <summary>
        /// Method that returns a DataTable with the result of SQL query
        /// </summary>
        /// <returns>DataTable</returns>
        /// <remarks>
        /// Author: Marco Octávio
        /// Last Update: 02/02/2009
        /// </remarks>
        public DataTable GetDataTable()
        {
            DataTable dte = new DataTable();
            try
            {
                DbDataReader drr = scope.Command.ExecuteReader();
                dte.Load(drr);
                FinalizeSqlExecution(false);
            }
            catch (SqlException e)
            {
                FinalizeSqlExecution(true);
                dte = null;
                throw e;
            }
            catch (Exception e)
            {
                FinalizeSqlExecution(true);
                dte = null;
                throw e;
            }
            return dte;
        }

        /// <summary>
        /// Method that returns a DataTable with the result of SQL query
        /// </summary>
        /// <returns>DataSet</returns>
        /// <remarks>
        /// Author: Marco Octávio
        /// Last Update: 02/02/2009
        /// </remarks>
        public DataSet GetDataSet()
        {
            DataSet dst = new DataSet();
            try
            {
                DbDataAdapter adapter = scope.Provider.CreateDataAdapter();
                adapter.SelectCommand = scope.Command;
                adapter.Fill(dst);
                FinalizeSqlExecution(false);
            }
            catch (SqlException e)
            {
                FinalizeSqlExecution(true);
                dst = null;
                throw e;
            }
            catch (Exception e)
            {
                FinalizeSqlExecution(true);
                dst = null;
                throw e;
            }
            return dst;
        }

        /// <summary>
        /// Method that returns a typed DataTable.
        /// </summary>
        /// <typeparam name="T">Type of return and DataTable</typeparam>
        /// <returns>Typed DataTable</returns>
        /// <remarks>
        /// Author: Marco Octávio
        /// Last Update: 02/02/2009
        /// </remarks>
        public T GetDataTable<T>() where T : DataTable, new()
        {
            T tDataTable = new T();
            try
            {
                DbDataReader drr = scope.Command.ExecuteReader();
                tDataTable.Load(drr);
                FinalizeSqlExecution(false);
            }
            catch (SqlException e)
            {
                FinalizeSqlExecution(true);
                tDataTable = null;
                throw e;
            }
            catch (Exception e)
            {
                FinalizeSqlExecution(true);
                tDataTable = null;
                throw e;
            }
            return tDataTable;
        }

        /// <summary>
        /// Method that returns a typed DataSet.
        /// </summary>
        /// <typeparam name="T">Type of return and DataSet</typeparam>
        /// <returns>Typed DataSet</returns>
        /// <remarks>
        /// Author: Marco Octávio
        /// Last Update: 02/02/2009
        /// </remarks>
        public T GetDataSet<T>() where T : DataSet, new()
        {
            T tDataSet = new T();
            try
            {
                DbDataAdapter adapter = scope.Provider.CreateDataAdapter();
                adapter.SelectCommand = scope.Command;
                adapter.Fill(tDataSet);
                FinalizeSqlExecution(false);
            }
            catch (SqlException e)
            {
                FinalizeSqlExecution(true);
                tDataSet = null;
                throw e;
            }
            catch (Exception e)
            {
                FinalizeSqlExecution(true);
                tDataSet = null;
                throw e;
            }
            return tDataSet;
        }

        /// <summary>
        /// Method that returns a typed DataSet.
        /// </summary>
        /// <typeparam name="T">Type of return and DataSet</typeparam>
        /// <returns>Typed DataSet</returns>
        /// <remarks>
        /// Author: Marco Octávio
        /// Last Update: 02/02/2009
        /// </remarks>
        public T GetDataSet<T>(params string[] srcTables) where T : DataSet, new()
        {
            T tDataSet = new T();
            try
            {
                DbDataAdapter adapter = scope.Provider.CreateDataAdapter();
                adapter.SelectCommand = scope.Command;
                ConfigTableMapping(srcTables, adapter);
                adapter.Fill(tDataSet);
                FinalizeSqlExecution(false);
            }
            catch (SqlException e)
            {
                FinalizeSqlExecution(true);
                tDataSet = null;
                throw e;
            }
            catch (Exception e)
            {
                FinalizeSqlExecution(true);
                tDataSet = null;
                throw e;
            }
            return tDataSet;
        }

        /// <summary>
        /// Method that adds the table mapping to the adapter object.
        /// </summary>
        /// <param name="srcTables">List of the datatable names</param>
        /// <param name="adapter">the adapter which is used to fill the dataset</param>
        private static void ConfigTableMapping(string[] srcTables, DbDataAdapter adapter)
        {
            for (int i = 0; i < srcTables.Length; i++)
            {
                string table = srcTables[i];
                string datatableName = "Table" + (i == 0 ? string.Empty : i.ToString());
                adapter.TableMappings.Add(datatableName, table);
            }
        }

        /// <summary>
        /// Executes SQL declarations that doesn't returns data, like Insert, Update, Delete and Set.
        /// </summary>
        /// <returns>The number of rows affected by the SQL command</returns>
        /// <remarks>
        /// Author: Marco Octávio
        /// Last Update: 04/02/2009
        /// </remarks>
        public int ExecuteNonQuery()
        {
            int result;
            try
            {
                result = scope.Command.ExecuteNonQuery();
                FinalizeSqlExecution(false);
            }
            catch (SqlException e)
            {
                FinalizeSqlExecution(true);
                result = -1;
                throw e;
            }
            catch (Exception e)
            {
                FinalizeSqlExecution(true);
                result = -1;
                throw e;
            }
            return result;
        }

        /// <summary>
        /// Executes the command and returns the result of the first column of the first row of the resultset.
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// Author: Marco Octávio
        /// Last Update: 04/02/2009
        /// </remarks>
        public object ExecuteScalar()
        {
            object result = null;
            try
            {
                result = scope.Command.ExecuteScalar();
                FinalizeSqlExecution(false);
            }
            catch (SqlException e)
            {
                FinalizeSqlExecution(true);
                throw e;
            }
            catch (Exception e)
            {
                FinalizeSqlExecution(true);
                throw e;
            }
            return result;
        }

        /// <summary>
        /// ExecuteScalar method overload that returns an object of the same type passed as parameter
        /// </summary>
        /// <typeparam name="T">Type of object</typeparam>
        /// <returns></returns>
        public T ExecuteScalar<T>()
        {
            T result = default(T);
            try
            {
                result = (T)scope.Command.ExecuteScalar();
                FinalizeSqlExecution(false);
            }
            catch (SqlException e)
            {
                FinalizeSqlExecution(true);
                throw e;
            }
            catch (Exception e)
            {
                FinalizeSqlExecution(true);
                throw e;
            }
            return result;
        }

        /// <summary>
        /// Executes a SQL query and returns tha data in a DbDataReader object.
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// Author: Marco Octávio
        /// Last Update: 04/02/2009
        /// </remarks>
        public DbDataReader ExecuteReader()
        {
            DbDataReader drr = null;
            try
            {
                drr = scope.Command.ExecuteReader();
                FinalizeSqlExecution(false);
            }
            catch (SqlException e)
            {
                FinalizeSqlExecution(true);
                throw e;
            }
            catch (Exception e)
            {
                FinalizeSqlExecution(true);
                throw e;
            }
            return drr;
        }

        #endregion Declaring Methods

        */
    }
}